Micron Document
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| SparkN0de-git | SparkN0de |
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Node / ReticulumProjects / MeshChatX.git / files / meshchatx / android_codec2.py

Displaying Raw • Download


meshchatx/android_codec2.py c0b0ddffd735a0d007c1be9a5e8563ec42fdafc0 (c0b0ddff) Text, 4.15 KB

T8b949e# SPDX-License-Identifier: 0BSD

T8b949e"""Load Codec2 native libraries before pycodec2/LXST on Chaquopy Android."""

Tff7b72from T7ee787__future__ Tff7b72import Te6edf3annotations

Tff7b72import T7ee787ctypes
Tff7b72import T7ee787logging
Tff7b72import T7ee787os
Tff7b72import T7ee787sys
Tff7b72from T7ee787pathlib Tff7b72import Te6edf3Path

Te6edf3logger Tff7b72= Te6edf3loggingTff7b72.Td2a8ffgetLoggerTb4b4b4(Tff7b72__name__Tb4b4b4)

Te6edf3_codec2_preload_errorTb4b4b4: Tffa657str Tff7b72| Tff7b72None Tff7b72= Tff7b72None
Te6edf3_codec2_preload_done Tff7b72= Tff7b72False


Tff7b72def Td2a8ff_is_chaquopy_androidTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
Tff7b72tryTb4b4b4:
Tff7b72import T7ee787java T8b949e# noqa: F401
Tff7b72except Tf85149ImportErrorTb4b4b4:
Tff7b72return Tff7b72False
Tff7b72return Tff7b72True


Tff7b72def Td2a8ff_cdll_loadTb4b4b4(Te6edf3path_or_nameTb4b4b4: Tffa657strTb4b4b4)Tb4b4b4:
T8b949e"""Load a shared library with RTLD_GLOBAL when the platform supports it.

pycodec2.so declares NEEDED libcodec2.so. Loading with RTLD_GLOBAL lets the
later dlopen of the extension resolve that dependency.
"""
Te6edf3mode Tff7b72= Tffa657getattrTb4b4b4(Te6edf3ctypesTb4b4b4, Ta5d6ff"Ta5d6ffRTLD_GLOBALTa5d6ff"Tb4b4b4, Tff7b72NoneTb4b4b4)
Tff7b72if Te6edf3mode Tff7b72is Tff7b72NoneTb4b4b4:
Tff7b72return Te6edf3ctypesTff7b72.Td2a8ffCDLLTb4b4b4(Te6edf3path_or_nameTb4b4b4)
Tff7b72return Te6edf3ctypesTff7b72.Td2a8ffCDLLTb4b4b4(Te6edf3path_or_nameTb4b4b4, Te6edf3modeTff7b72=Te6edf3modeTb4b4b4)


Tff7b72def Td2a8ff_libcodec2_candidatesTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657listTb4b4b4[Te6edf3PathTb4b4b4]Tb4b4b4:
T8b949e"""Return candidate paths for libcodec2.so without importing pycodec2.

import pycodec2 loads the extension which already needs libcodec2.so.
Searching sys.path on disk avoids that chicken-and-egg failure.
"""
Te6edf3candidatesTb4b4b4: Tffa657listTb4b4b4[Te6edf3PathTb4b4b4] Tff7b72= Tb4b4b4[Tb4b4b4]
Te6edf3seenTb4b4b4: Tffa657setTb4b4b4[Tffa657strTb4b4b4] Tff7b72= Tffa657setTb4b4b4(Tb4b4b4)

Tff7b72def Td2a8ffaddTb4b4b4(Te6edf3pathTb4b4b4: Te6edf3PathTb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
Te6edf3key Tff7b72= Tffa657strTb4b4b4(Te6edf3pathTb4b4b4)
Tff7b72if Te6edf3key Tff7b72in Te6edf3seenTb4b4b4:
Tff7b72return
Te6edf3seenTff7b72.Td2a8ffaddTb4b4b4(Te6edf3keyTb4b4b4)
Te6edf3candidatesTff7b72.Td2a8ffappendTb4b4b4(Te6edf3pathTb4b4b4)

Te6edf3explicit Tff7b72= Te6edf3PathTb4b4b4(Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffgetTb4b4b4(Ta5d6ff"Ta5d6ffMESHCHAT_LIBCODEC2_PATHTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72if Te6edf3explicitTff7b72.Td2a8ffis_fileTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3addTb4b4b4(Te6edf3explicitTb4b4b4)

Tff7b72for Te6edf3entry Tff7b72in Te6edf3sysTff7b72.Td2a8ffpathTb4b4b4:
Tff7b72if Tff7b72not Te6edf3entryTb4b4b4:
Tff7b72continue
Te6edf3root Tff7b72= Te6edf3PathTb4b4b4(Te6edf3entryTb4b4b4)
Te6edf3addTb4b4b4(Te6edf3root Tff7b72/ Ta5d6ff"Ta5d6ffpycodec2Ta5d6ff" Tff7b72/ Ta5d6ff"Ta5d6fflibcodec2.soTa5d6ff"Tb4b4b4)
Te6edf3addTb4b4b4(Te6edf3root Tff7b72/ Ta5d6ff"Ta5d6ffchaquopyTa5d6ff" Tff7b72/ Ta5d6ff"Ta5d6fflibTa5d6ff" Tff7b72/ Ta5d6ff"Ta5d6fflibcodec2.soTa5d6ff"Tb4b4b4)
T8b949e# Some Chaquopy layouts nest native libs under site-packages directly.
Te6edf3addTb4b4b4(Te6edf3root Tff7b72/ Ta5d6ff"Ta5d6fflibcodec2.soTa5d6ff"Tb4b4b4)

T8b949e# Extracted APK native lib dirs (ABI-specific jniLibs sync target).
Tff7b72for Te6edf3env_key Tff7b72in Tb4b4b4(Ta5d6ff"Ta5d6ffMESHCHAT_NATIVE_LIB_DIRTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffANDROID_NATIVE_LIBRARY_DIRTa5d6ff"Tb4b4b4)Tb4b4b4:
Te6edf3native_dir Tff7b72= Te6edf3PathTb4b4b4(Te6edf3osTff7b72.Td2a8ffenvironTff7b72.Td2a8ffgetTb4b4b4(Te6edf3env_keyTb4b4b4, Ta5d6ff"Ta5d6ff"Tb4b4b4) Tff7b72or Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72if Te6edf3native_dirTff7b72.Td2a8ffis_dirTb4b4b4(Tb4b4b4)Tb4b4b4:
Te6edf3addTb4b4b4(Te6edf3native_dir Tff7b72/ Ta5d6ff"Ta5d6fflibcodec2.soTa5d6ff"Tb4b4b4)

Tff7b72return Te6edf3candidates


Tff7b72def Td2a8ffensure_codec2_native_libraryTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657boolTb4b4b4:
T8b949e"""Preload libcodec2.so so import pycodec2 works on Android.

Chaquopy installs chaquopy-libcodec2 separately from pycodec2. The
extension module only declares a NEEDED entry for libcodec2.so. Without
preloading or bundling the shared library next to pycodec2.so, imports
fail at runtime with dlopen errors.
"""
Tff7b72global Te6edf3_codec2_preload_doneTb4b4b4, Te6edf3_codec2_preload_error

Tff7b72if Te6edf3_codec2_preload_doneTb4b4b4:
Tff7b72return Te6edf3_codec2_preload_error Tff7b72is Tff7b72None

Te6edf3_codec2_preload_done Tff7b72= Tff7b72True

Tff7b72if Tff7b72not Te6edf3_is_chaquopy_androidTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72True

Tff7b72tryTb4b4b4:
Te6edf3_cdll_loadTb4b4b4(Ta5d6ff"Ta5d6fflibcodec2.soTa5d6ff"Tb4b4b4)
Tff7b72return Tff7b72True
Tff7b72except Tf85149OSErrorTb4b4b4:
Tff7b72pass

Te6edf3last_errorTb4b4b4: Tffa657str Tff7b72| Tff7b72None Tff7b72= Tff7b72None
Tff7b72for Te6edf3lib_path Tff7b72in Te6edf3_libcodec2_candidatesTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72if Tff7b72not Te6edf3lib_pathTff7b72.Td2a8ffis_fileTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72continue
Tff7b72tryTb4b4b4:
Te6edf3_cdll_loadTb4b4b4(Tffa657strTb4b4b4(Te6edf3lib_pathTb4b4b4)Tb4b4b4)
Te6edf3loggerTff7b72.Td2a8ffinfoTb4b4b4(Ta5d6ff"Ta5d6ffLoaded Codec2 native library from Tffd700%sTa5d6ff"Tb4b4b4, Te6edf3lib_pathTb4b4b4)
Tff7b72return Tff7b72True
Tff7b72except Tf85149OSError Tff7b72as Te6edf3excTb4b4b4:
Te6edf3last_error Tff7b72= Ta5d6fffTa5d6ff"Tffd700{Te6edf3lib_pathTffd700}Ta5d6ff: Tffd700{Te6edf3excTffd700}Ta5d6ff"

Te6edf3_codec2_preload_error Tff7b72= Te6edf3last_error Tff7b72or Ta5d6ff"Ta5d6fflibcodec2.so not found on AndroidTa5d6ff"
Te6edf3loggerTff7b72.Td2a8ffwarningTb4b4b4(Ta5d6ff"Ta5d6ffCodec2 native preload failed: Tffd700%sTa5d6ff"Tb4b4b4, Te6edf3_codec2_preload_errorTb4b4b4)
Tff7b72return Tff7b72False


Tff7b72def Td2a8ffprobe_pycodec2Tb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657tupleTb4b4b4[Tffa657boolTb4b4b4, Tffa657str Tff7b72| Tff7b72NoneTb4b4b4]Tb4b4b4:
T8b949e"""Import pycodec2 after preload and report whether Codec2 works."""
Tff7b72if Te6edf3_is_chaquopy_androidTb4b4b4(Tb4b4b4) Tff7b72and Tff7b72not Te6edf3ensure_codec2_native_libraryTb4b4b4(Tb4b4b4)Tb4b4b4:
Tff7b72return Tff7b72FalseTb4b4b4, Te6edf3codec2_preload_errorTb4b4b4(Tb4b4b4)
Tff7b72tryTb4b4b4:
Tff7b72import T7ee787pycodec2

Te6edf3c2 Tff7b72= Te6edf3pycodec2Tff7b72.Td2a8ffCodec2Tb4b4b4(T79c0ff1600Tb4b4b4)
Te6edf3_ Tff7b72= Te6edf3c2Tff7b72.Td2a8ffsamples_per_frameTb4b4b4(Tb4b4b4)
Tff7b72return Tff7b72TrueTb4b4b4, Tff7b72None
Tff7b72except Tf85149Exception Tff7b72as Te6edf3excTb4b4b4:
Tff7b72return Tff7b72FalseTb4b4b4, Tffa657strTb4b4b4(Te6edf3excTb4b4b4)


Tff7b72def Td2a8ffcodec2_preload_errorTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tffa657str Tff7b72| Tff7b72NoneTb4b4b4:
T8b949e"""Return the last preload failure message, if any."""
Tff7b72return Te6edf3_codec2_preload_error


Tff7b72def Td2a8ffreset_codec2_preload_state_for_testsTb4b4b4(Tb4b4b4) Tff7b72-Tff7b72> Tff7b72NoneTb4b4b4:
T8b949e"""Clear preload memoization (tests only)."""
Tff7b72global Te6edf3_codec2_preload_doneTb4b4b4, Te6edf3_codec2_preload_error
Te6edf3_codec2_preload_done Tff7b72= Tff7b72False
Te6edf3_codec2_preload_error Tff7b72= Tff7b72None


──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────